package vip.xiaonuo.core.util;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaSignException;
import cn.dev33.satoken.sign.SaSignTemplate;
import cn.dev33.satoken.sign.SaSignUtil;
import cn.hutool.core.util.ArrayUtil;
import jakarta.servlet.http.HttpServletRequest;
import vip.xiaonuo.common.exception.CommonException;

import java.util.HashMap;
import java.util.Map;

import static cn.dev33.satoken.sign.SaSignUtil.checkNonce;

public class MySaSignUtil {
    /**
     * 校验：一个请求的 nonce、timestamp、sign 是否均为合法的，如果不合法，则抛出对应的异常
     * @param request 待校验的请求对象
     */
    public static void checkRequest(HttpServletRequest request,String body) {
        // 获取必须的三个参数
        String timestampValue = request.getHeader("timestamp");
        String nonceValue = request.getHeader("nonce");
        String signValue = request.getHeader("sign");

        // 参数非空校验
        SaSignException.throwByNull(timestampValue, "缺少 timestamp 字段");
        // SaSignException.throwByNull(nonceValue, "缺少 nonce 字段"); // 配置isCheckNonce=false时，可以不传 nonce
        SaSignException.throwByNull(signValue, "缺少 sign 字段");

        SaSignTemplate sst= new SaSignTemplate();
        // 依次校验三个参数
        sst.checkTimestamp(Long.parseLong(timestampValue));

        //前置效验完毕，开发核验参数是否被篡改

        //判断请求类型
        String method = request.getMethod();
        if("GET".equalsIgnoreCase(method)) {
            //防止重复请求
            if(sst.getSignConfigOrGlobal().getIsCheckNonce()) {
                checkNonce(nonceValue);
            }
            Map<String, String[]> map = request.getParameterMap();
            Map<String, String> paramsMap = new HashMap<String, String>();
            for (Map.Entry<String, String[]> e : map.entrySet()) {
                String key = e.getKey();
                String[] result = e.getValue();
                String value = ArrayUtil.join(result, ",");

                paramsMap.put(key, value);
            }
            paramsMap.put("timestamp", timestampValue);
            paramsMap.put("nonce", nonceValue);
            //get按常规方式核验
            sst.checkSign(paramsMap, signValue);
        }else if("POST".equalsIgnoreCase(method)) {
            String contentType = request.getHeader("Content-Type");
            if("application/json".equalsIgnoreCase(contentType)) {
                //防止重复请求
                if(sst.getSignConfigOrGlobal().getIsCheckNonce()) {
                    checkNonce(nonceValue);
                }
                //json格式的参数才效验，文件上传不处理
                body += "&nonce=" + nonceValue + "&timestamp=" + timestampValue + "&key=" + sst.getSecretKey();
                String newSign = sst.abstractStr(body);
                if (!signValue.equals(newSign)) {
                    throw new SaSignException("无效签名：" + signValue).setCode(SaErrorCode.CODE_12202);
                }

            }
        }
    }
}
